David O’Sullivan & Luke R Bergmann
The TL;DR;
Two new kinds of thematic map for handling complex multivariate data associated with polygons.
We’ve developed python code that helps you make tiled and woven maps.
Mosaic world map by Chris Chamberlain; see this article and this video for more.
“… a countable family of closed sets \(\mathcal{T}=\{T_1,T_2,\ldots\}\) which covers the plane without gaps or overlaps. More explicitly, the union of the sets \(T_1,T_2,\ldots\) (which are known as the tiles of \(\mathcal{T}\)) is to be the whole plane, and the interiors of the sets \(T_i\) are to be pairwise disjoint” (Grünbaum and Shephard 1987, page 16)
… a GIS coverage!
The symmetries of a tiling map tiles on to other tiles.
The sets of tiles related to one another in this way are the transitivity groups of the tiling.
An isohedral tiling has only one transitivity group.
Directionality or orientation is irrelevant to mathematicians because they consider tiles and tilings identical under rotation.
However, they are important for mapping. Many isohedral tilings contain directionally distinguishable tiles.
We likely need a new cartographic notion of the transitivity groups where different tile orientations ‘count’ as different.
¯\_(ツ)_/¯
We are not entirely sure… yet!
The building blocks of our approach.
triangles = TileUnit(tile_shape = TileShape.TRIANGLE)
squares = TileUnit()
hexagons = TileUnit(tile_shape = TileShape.HEXAGON)These (and more) are all available with the same command:
tile = TileUnit(
tiling_type = "cairo|archimedean|laves|hex-dissection|square-dissection",
n = ..., code = "3.3.4.3.4", dissection_offset = 0|1, # optional
spacing = 500, crs = 2193
)We can then make various adjustments:
Insetting relative to the repeating tile unit helps distinguish elements.
For a lot more on woven maps, see our earlier talk.
Weaving theory leads to useful matrix-based approaches.
Primarily for biaxial weaves.
We (eventually) figured out how to extend the matrix approach to triaxial weaves (see our notes).
We make these the same way we make tile units.
w1 = WeaveUnit(weave_type = "twill", n = 3, aspect = .9,
strands = "ab-|cde-")
w2 = WeaveUnit(weave_type = "cube", aspect = .8,
strands = "a-c|d-f|g-i")The strands parameter specifies which strands in each axis (separated by the "|") are distinct, and also allows us to ‘skip’ strands on "-" characters .
Vermeer’s The Geographer (∽1675) from commons.wikimedia.org.
Making a tiled map, TileUnits and WeaveUnits are both Tileable objects and are treated the same.
We make a Tiling from one of these along with a polygon dataset to be tiled.
The Tiling generates a TileGrid which controls copying and translating the tileable units into a tiled or woven map.
Next, make a TiledMap by calling the get_tiled_map() method of the Tiling.
This controls combining the Tiling with the geospatial data by overlay and dissolve operations.
Here we can choose to emphasize tile boundaries, or zone boundaries in the dataset using the prioritise_tiles setting.
Here we have to specify the mapping from tileable element identifiers ("a", "b", "c" …) to data variables.
We also specify the mapping from variable names to chosen colour palettes.
tiled_map.colourmaps = dict(zip(tiled_map.variables.values(),
("Reds", "Blues", "Greens", "Greys")))Now we can render a map…
There are a range of options here particularly in relation to the tricky business of generating a legend.
Because we can…